package cn.edu.hgu.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import cn.edu.hgu.dao.BaseDao;
import cn.edu.hgu.util.PageResult;

public class BaseDaoImpl<T> implements BaseDao<T> {

	private Class<T> clazz;
	@Autowired
	private SessionFactory sessionFactory;

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	
	public BaseDaoImpl() {
		Type type = this.getClass().getGenericSuperclass();
		if(type instanceof ParameterizedType) {
			ParameterizedType pType = (ParameterizedType) type;
			clazz = (Class<T>) pType.getActualTypeArguments()[0];
		}
	}
	
	public void insert(T t) {
		sessionFactory.getCurrentSession().save(t);
	}

	public void deleteById(Integer id) {
		sessionFactory.getCurrentSession().delete(findById(id));
	}

	public void update(T t) {
		sessionFactory.getCurrentSession().update(t);
	}

	public T findById(Integer id) {
		return (T) sessionFactory.getCurrentSession().get(clazz, id);
	}
	
	public List<T> findAll() {
		return (List<T>) sessionFactory.getCurrentSession().createQuery("from " + clazz.getSimpleName()).list();
	}
	
	public List<T> findByConditions(String conditions, List<Object> params) {
		StringBuilder hql = new StringBuilder(80);
		hql.append("from ").append(clazz.getSimpleName());
		if(conditions != null) {
			hql.append(" " + conditions);
		}
		Query query = sessionFactory.getCurrentSession().createQuery(hql.toString());
		setPlaceholder(params, query);
		return (List<T>) query.list();
	}
	
	public PageResult<T> findByPage(String conditions, PageResult<T> pageResult, List<Object> params) {
		StringBuilder hql = new StringBuilder(80);
		hql.append("select count(*) from ").append(clazz.getSimpleName());
		if(conditions != null) {
			hql.append(" ").append(conditions);
		}
		Query query = sessionFactory.getCurrentSession().createQuery(hql.toString());
		setPlaceholder(params, query);
		int count = ((Long) query.uniqueResult()).intValue();
		pageResult.setTotalRecords(count);
		hql = new StringBuilder(80);
		hql.append("from ").append(clazz.getSimpleName());
		if(conditions != null) {
			hql.append(" ").append(conditions);
		}
		query = sessionFactory.getCurrentSession().createQuery(hql.toString());
		setPlaceholder(params, query);
		List<T> list = (List<T>) query.setFirstResult((pageResult.getPageNo() - 1) * pageResult.getPageSize()).setMaxResults(pageResult.getPageSize()).list();
		pageResult.setRecord(list);
		return pageResult;
	}

	private void setPlaceholder(List<Object> params, Query query) {
		if (params != null && params.size() > 0) {
			for (int i = 0; i < params.size(); i++) {
				query.setParameter(i, params.get(i));
			}
		}
	}

}
